/*
 *  sci_server_lib.c
 *  PointerTest
 *
 *  Created by Jonatan Werpers on 5/3/11.
 *  Copyright 2011 __MyCompanyName__. All rights reserved.
 *
 */

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "sci_server_lib.h"

char const *inBufferEnd = &inBuffer[IN_BUF - 1];
int cmdCounter = 0;
//Defining commands
struct Command cmdList[NR_CMD] = {
	{"help",&cmdHelp},
	{"get",&cmdGet},
	{"set",&cmdSet},
	{"vars",&cmdVars},
};
//When a handling function has finished running, the readPtr should be pointing to the first character of the next cmd.

void cmdHelp(){
	printf("Avalible commands are:\n");
	int i;
	for (i = 0; i < NR_CMD; i++) {
		fputs("  ", stdout);
		fputs(cmdList[i].name, stdout);
	}
	printf("\n");
}
void cmdGet(){
	int *var;
	if (*(readPtr - 1) != '\n') {
		printf("Getting!\n");
		var = getVar();
		if(var != NULL) {
			printf("Value: %d\n\n",*var);
		} else {
			inputError("Hoho! Variabeln hittades inte!");
		}
	} else {
		readPtr--; //Make sure the next cmd doesn't get skipped by inputError()
		inputError("Parameters were expected!");
	}
	
	
}
void cmdSet(){
	int *var;
	char value[MAX_WORD_LENGTH];
	printf("Setting!\n\n");
	var = getVar();
	if(var != NULL) {
		//TODO tolka nästa ord som ett tal och sätt variablen till det.
		getNextWord(value);
		*var = atoi(value);
	} else {
		inputError("Hoho! Variabeln hittades inte!");
	}
}
void cmdVars(){
	int i;
	for (i = 0; i < NR_VAR; i++) {
		fputs(varList[i].name, stdout);
		fputs(" : ", stdout);
		printf("%d\n",*(varList[i].varPtr));
	}
	printf("\n");
}

void readNextCommand(){
	char *s, *r;
	int i;
	
#if MULTI_CHIP_SETUP
	r = compareToBuffer(CHIP_ID);
	if (r == NULL) {
		//The id doesn't match the id of this chip
		
		//Skip command
		while (*readPtr != '\n') {
			incInPtr(readPtr);
		}
		incInPtr(readPtr);
		return;
	} else {
		readPtr = r;
	}
	
#endif
	
	for (i = 0;i < NR_CMD; i++) {
		s = cmdList[i].name;
		r = compareToBuffer(s);
		if (r != NULL) {
			//We have a match
			readPtr = r;
			cmdList[i].functionPtr();
			return;
		}
	}
	// we have checked all commands and none matched
	inputError("No such command");
	return;
}

//If the next word in the buffer is a variable a pointer to that variable is returned
//Returns NULL if an error occured
int * getVar(){
	char *s, *r;
	int i;
	
	for (i = 0;i < NR_VAR; i++) {
		s = varList[i].name;
		r = compareToBuffer(s);
		
		if (r != NULL) {
			//We have a match
			readPtr = r;
			return varList[i].varPtr;
		}
	}
	return NULL;
}

//Input is a char array to put the next word of inBuffer in
//Returns 1 if successfull
//Returns 0 if an error occured
int getNextWord(char *s){
	int i;
	for (i = 0; i < MAX_WORD_LENGTH && !isWS(*readPtr); i++) {
		*s++ = *readPtr;
		incInPtr(readPtr);
	}
	
	if (isWS(*readPtr)) {
		//End the string
		*s = '\0';
		
		//skip the ' ' or '\n'
		incInPtr(readPtr);
		
		return 1;
	}else {
		//The word was too long!
		inputError("A word in the command was too long!");
		return 0;
	}
	
}

void inputError(char * errMsg){
	//Sends error msg and moves readPtr to beginning of next cmd
	while (*readPtr != '\n') {
		incInPtr(readPtr);
	}
	incInPtr(readPtr); //Skip the NEWLINE
	puts(errMsg);
}

void writeToBuffer(char *s){
	while (*s != '\0') {
		if(*s == '\n'){cmdCounter++;}
		*rxPtr = *s++;
		incInPtr(rxPtr);
	}
}

//Comdpares s1 to the next word in the buffer
//Returns NULL if no match was found. Otherwise returns the address of next read.
char * compareToBuffer(char * s1){
	char * s2 = readPtr;
	while (*s1 == *s2 && s1 != '\0') {
		s1++;
		incInPtr(s2);
	}
	if (*s1 == '\0' && isWS(*s2)) {
		incInPtr(s2); //Skip white space
		return s2;
	} else {
		return NULL;
	}
	
}